import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;


public class ArrowLine extends JPanel{

	private Point startPoint,endPoint;
	private static final int WIDTH=3;
	private boolean horizontal;
	private boolean drawArrow;
	private boolean dragFlag;
	private boolean bad;
	private Point startDragPoint; 
	
	
	public ArrowLine(Point startPoint,Point endPoint) {
		this.startPoint=startPoint;
		this.endPoint=endPoint;

		setLocation();
		dragFlag=false;		
	}
	
	public void setStartPoint(Point startPoint){
		this.startPoint=startPoint;
		setLocation();
	}
	
	public void setEndPoint(Point endPoint){
		this.endPoint=endPoint;
		setLocation();
	}
	
	public void stopDrag(){
		dragFlag=false;
	}
	
	public boolean isDragging(){
		return dragFlag;
	}
	
	public void startDrag(Point startDragPoint){
		dragFlag=true;
		this.startDragPoint=startDragPoint;
	}
	
	public Point getStartDragPoint(){
		return startDragPoint;
	}
	
	private void setLocation() {
		int dx=(int)Math.abs(startPoint.x-endPoint.x);
		int dy=(int)Math.abs(startPoint.y-endPoint.y);
		if(dx>dy){
			horizontal=true;
			setLocation(Math.min(startPoint.x, endPoint.x),startPoint.y-WIDTH);
			endPoint=new Point(endPoint.x,startPoint.y);			
			setSize((int)Math.abs(startPoint.x-endPoint.x),WIDTH*2);
		}
		else{
			horizontal=false;
			setLocation(startPoint.x-WIDTH,Math.min(startPoint.y, endPoint.y));
			endPoint=new Point(startPoint.x,endPoint.y);			
			setSize(WIDTH*2,(int)Math.abs(startPoint.y-endPoint.y));
		}
	}
	
	public void paintComponent(Graphics gr){
		Graphics2D gr2d=(Graphics2D)gr;
		gr2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		gr2d.setColor(Color.BLACK);
		if(horizontal){
			gr2d.drawLine(0, WIDTH, getWidth(), WIDTH);
			if(drawArrow){
				if(startPoint.x>endPoint.x){
					if(!bad){
						gr2d.drawLine(0, WIDTH,2*WIDTH, 0);
						gr2d.drawLine(0, WIDTH,2*WIDTH, 2*WIDTH-1);
					}
					else{
						gr2d.drawLine(0, 0, 2*WIDTH, 2*WIDTH-1);
						gr2d.drawLine(0, 2*WIDTH-1, 2*WIDTH, 0);
					}
				}
				else{
					if(!bad){
						gr2d.drawLine(getWidth(), WIDTH, getWidth()-2*WIDTH, 0);
						gr2d.drawLine(getWidth(), WIDTH, getWidth()-2*WIDTH, 2*WIDTH-1);
					}
					else{
						gr2d.drawLine(getWidth(), 0, getWidth()-2*WIDTH, 2*WIDTH-1);
						gr2d.drawLine(getWidth(), 2*WIDTH-1, getWidth()-2*WIDTH, 0);
					}
				}
			}
		}
		else{
			gr2d.drawLine(WIDTH,0,WIDTH,getHeight());
			if(drawArrow){
				if(startPoint.y>endPoint.y){
					if(!bad){
						gr2d.drawLine(WIDTH, 0, 0, 2*WIDTH);
						gr2d.drawLine(WIDTH, 0, 2*WIDTH-1, 2*WIDTH);
					}
					else{
						gr2d.drawLine(0, 0, 2*WIDTH-1, 2*WIDTH);
						gr2d.drawLine(2*WIDTH-1, 0, 0, 2*WIDTH);
					}
				}
				else{
					if(!bad){
						gr2d.drawLine(WIDTH, getHeight(), 0, getHeight()-2*WIDTH);
						gr2d.drawLine(WIDTH, getHeight(), 2*WIDTH-1, getHeight()-2*WIDTH);
					}
					else{
						gr2d.drawLine(0, getHeight(), 2*WIDTH-1, getHeight()-2*WIDTH);
						gr2d.drawLine(0, getHeight()-2*WIDTH, 2*WIDTH-1, getHeight());
					}
				}
			}
		}
			
	}
	
	public void setDrawArrow(boolean state,boolean bad){
		drawArrow=state;
		this.bad=bad;
	}
	
	public void recalcPoints(){
		if(horizontal){
			if(startPoint.x>endPoint.x){
				startPoint=new Point(getX()+getWidth(),getY()+WIDTH);
				endPoint=new Point(getX(),getY()+WIDTH);
			}
			else{
				startPoint=new Point(getX(),getY()+WIDTH);
				endPoint=new Point(getX()+getWidth(),getY()+WIDTH);
			}
		}
		else{
			if(startPoint.y>endPoint.y){
				startPoint=new Point(getX()+WIDTH,getY()+getHeight());
				endPoint=new Point(getX()+WIDTH,getY());
			}
			else{
				startPoint=new Point(getX()+WIDTH,getY());
				endPoint=new Point(getX()+WIDTH,getY()+getHeight());
			}
		}
	}
	
	public Point getStartPoint(){
		return startPoint;
	}
	
	public Point getEndPoint(){
		return endPoint;
	}
	
	public boolean isHorizontal(){
		return horizontal;
	}
}
